
#include "normal.h"

/* Given two points pIn and pOffset, the function calculates 
   the vector of these two functions to pOut */
void VectorOffset (Point& pIn, Point& pOffset, Point& pOut)
{
	pOut.SetX( pIn.X() - pOffset.X());
	pOut.SetY( pIn.Y() - pOffset.Y());
	pOut.SetZ( pIn.Z() - pOffset.Z());
}

/* Given vectors a and b, the function calculates the normal of
   the two vectors to pOut. */
void VectorGetNormal (Point& a, Point& b, Point& pOut)
{
	pOut.SetX( a.Y() * b.Z() - a.Z() * b.Y());
	pOut.SetY( a.Z() * b.X() - a.X() * b.Z());
	pOut.SetZ( a.X() * b.Y() - a.Y() * b.X());
}

/* Since the returned vector from VectorGetNormal is not of unit length, 
   we normalize it so that it is. Asking OpenGL to do it would severly 
   reduce performance. */
int VectorNormalize (Point& pIn, Point& pOut)
{
		// The length of the vecor is len
	float len = (float)(sqrt ( (pIn.X()*pIn.X())+
		(pIn.Y()*pIn.Y())+(pIn.Z()*pIn.Z()) ));

		// If length is not equal to 0, then divide each element by the length.
		// This way the new length will be 1.
	if (len)
	{
		pOut.SetPoint ( pIn.X()/len, pIn.Y()/len, 
			pIn.Z()/len);
		return 1;
	}

		//If the length is 0, assign it the default normal config.
	pOut.SetPoint (0.0, 1.0, 0.0);
	return 0;
}

/* Given three points p0, p1 and p2, the function calculates the 
   normal of the plane that these three points make. */
void CalcNormal (Point& normal, Point& p0, Point& p1, Point& p2)
{
	Point a, b, tempNormal;

	VectorOffset (p1, p0, a);		// Get vector 1 
	VectorOffset (p2, p0, b);		// Get vector 2
	VectorGetNormal (a, b, tempNormal);		// Calculate the normal
	VectorNormalize (tempNormal, normal);	// Normalize the normal
}

/* Given two vectors p1 and p2, the dotprod calculate the dot product
   of these two vectors. Then, we return the scalar dot product. */
float DotProd (Point& p1, Point& p2)
{
	return (p1.X()*p2.X() + 
		p1.Y()*p2.Y() +
		p1.Z()*p2.Z());
}

/* The len function returns the length between points point1 and point2.
   The length is in absolute, so the order does not matter. */
float len (Point& point1, Point& point2)
{
	float x, y, z;
	
	x = point2.X() - point2.X();
	y = point2.Y() - point1.Y();
	z = point2.Z() - point2.Z();
	
	return (float)fabs(sqrt(x*x + y*y + z*z));
}